﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml;
using System.IO;

namespace MachineLearning {
   abstract class NeuralNetworkDataAdapter {
        protected SignalConditioner _sc = null;
        public SignalConditioner Conditioner {
            get { return _sc; }
        }
        protected string _dataSetName = null;
        public string DataSetName {
            get { return _dataSetName; }
        }
        protected string _dataSourceName = null;
        public string DataSourceName {
            get { return _dataSourceName; }
        }
        protected MediaType _media = MediaType.Text;
        public MediaType Media {
            get { return _media; }
        }
        protected OperationMode _opMode = OperationMode.Learn;
        public OperationMode OpMode {
            get { return _opMode; }
        }
        protected ProcessMode _procMode = ProcessMode.Batch;

        public enum MediaType {
            Text = 0,
            Image = 1,
            Video = 2,
            Audio = 3,
        }

        public enum OperationMode {
            Learn = 0,
            Validate = 1,
            Classify = 2,
        }

        public enum ProcessMode {
            Batch = 0,
            Online = 1,
        }


        public NeuralNetworkDataAdapter() {
            _sc = new SignalConditioner();
        }

        protected void readXml(string fileName) {
            StreamReader sr = new StreamReader(fileName);
            XmlDocument doc = new XmlDocument();
            doc.LoadXml(sr.ReadToEnd());
            sr.Close();
            XmlNode node = null;
            foreach (XmlNode n in doc.ChildNodes) {
                if (n.Name == "instances") {
                    _dataSetName = n.Attributes[0].Value;
                    _dataSourceName = n.Attributes[1].Value;
                    if (n.Attributes[2].Value == "text")
                        _media = MediaType.Text;
                    else if (n.Attributes[2].Value == "image")
                        _media = MediaType.Image;
                    else if (n.Attributes[2].Value == "video")
                        _media = MediaType.Video;
                    else if (n.Attributes[2].Value == "audio")
                        _media = MediaType.Audio;
                    if (n.Attributes[3].Value == "learn")
                        _opMode = OperationMode.Learn;
                    else if (n.Attributes[3].Value == "validate")
                        _opMode = OperationMode.Validate;
                    else if (n.Attributes[3].Value == "classify")
                        _opMode = OperationMode.Classify;
                    if (n.Attributes[4].Value == "batch")
                        _procMode = ProcessMode.Batch;
                    else if (n.Attributes[4].Value == "online")
                        _procMode = ProcessMode.Batch;
                    node = n;
                    break;
                }
            }
            //parse the IOs
            foreach (XmlNode n in node.ChildNodes) {
                if (n.Name == "input") {
                    _sc.InputConditioners.Add(new ScaleAndOffset(
                        double.Parse(n.Attributes[1].Value),
                        double.Parse(n.Attributes[2].Value)));
                } else if (n.Name == "output") {
                    _sc.OutputConditioners.Add(new ScaleAndOffset(
                        double.Parse(n.Attributes[1].Value),
                        double.Parse(n.Attributes[2].Value)));
                }
            }
        }


    }

    /// <summary>
    /// 
    /// </summary>
    class BatchNetworkAdapter : NeuralNetworkDataAdapter {
        protected Instance[] _instances = null;
        public Instance[] Instances {
            get { return _instances; }
        }

        public BatchNetworkAdapter(string fileName) : base() {
            readXml(fileName);
        }
    }

    /// <summary>
    /// 
    /// </summary>
    class TabNetworkAdapter : BatchNetworkAdapter {
        public TabNetworkAdapter(string fileName) : base(fileName) {
            if (_opMode == OperationMode.Learn || _opMode == OperationMode.Validate)
                _instances = ExampleReader.load(_dataSourceName
                    , _sc.InputConditioners.Count
                    , _sc.OutputConditioners.Count);
            else _instances = InstanceReader.load(_dataSourceName
                , _sc.InputConditioners.Count);
        }
    }

}
